﻿using System;
using System.Collections.Generic;
using Castle.MicroKernel.Registration;
using Castle.Windsor;

namespace Myotragus.Data.Containers.Windsor
{
	/// <summary>
	/// IServiceContainer implementation using Windsor serviceContainer
	/// </summary>
	public class ServicesContainer : IServicesRegistrar
	{
		#region Fields

		private WindsorContainer Container
		{
			get;
			set;
		}

		#endregion Fields

		#region Creation

		public ServicesContainer()
			: this(new WindsorContainer())
		{
		}

		public ServicesContainer(WindsorContainer container)
		{
			Container = container;
		}

		#endregion Creation

		#region IServiceContainer Members

		/// <inheritdoc/>
		public TService Resolve<TService>()
		{
			return (TService)Resolve(typeof(TService));
		}

		/// <inheritdoc/>
		public object Resolve(Type tService)
		{
			return Container.Resolve(tService);
		}

		#endregion IServiceContainer Members

		#region IConfigurableServiceRepository Members

		public ITypeRegistrar RegisterForAll(params Type[] implementations)
		{
			return RegisterForAll((IEnumerable<Type>)implementations);
		}

		public ITypeRegistrar RegisterForAll(IEnumerable<Type> implementations)
		{
			Container.Register(AllTypes.From(implementations).BasedOn<object>().
				WithService.AllInterfaces().Configure(c => c.LifeStyle.Singleton));
			return this;
		}

		public ITypeRegistrar RegisterForDefault(IEnumerable<Type> implementations)
		{
			Container.Register(AllTypes.From(implementations).BasedOn<object>().
				WithService.DefaultInterface());

			return this;
		}

		public ITypeRegistrar RegisterForDefault(params Type[] implementations)
		{
			return RegisterForDefault((IEnumerable<Type>)implementations);
		}

		public ITypeRegistrar RegisterFor(Type implementation, params Type[] interfaces)
		{
			return RegisterFor(implementation, (IEnumerable<Type>)interfaces);
		}

		public ITypeRegistrar RegisterFor(Type implementation, IEnumerable<Type> interfaces)
		{
			Container.Register(AllTypes.From(implementation).BasedOn<object>().
				WithService.Select(interfaces));

			return this;
		}

		#endregion IConfigurableServiceRepository Members
	}
}